using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using PasteFormHelper;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Domain.Repositories;

namespace OpenPasteSpider.projectmodel
{

    /// <summary>
    /// Container
    ///</summary>
    [TypeFilter(typeof(RoleAttribute), Arguments = new object[] { "data", "view" })]
    public class AppInfoAppService : OpenPasteSpiderAppService
    {

        private IOpenPasteSpiderDbContext _dbContext;
        public AppInfoAppService(IOpenPasteSpiderDbContext dbContext)
        {
            _dbContext = dbContext;
        }


        /// <summary>
        /// 
        /// </summary>
        /// <param name="page"></param>
        /// <param name="size"></param>
        /// <param name="serviceid"></param>
        /// <param name="model"></param>
        /// <returns></returns>
        [HttpGet]
        public async Task<PagedResultDto<AppInfoListDto>> GetListAsync([FromQuery] int page = 1, int size = 20, int serviceid = 0, string model = "")
        {
            if (serviceid != 0)
            {
                var query = from a in _dbContext.AppInfo
                            join b in _dbContext.ModelInfo.Where(x => x.Service.Id == serviceid) on a.ModelId equals b.Id
                            into c
                            from d in c.DefaultIfEmpty()
                            select new AppInfoListDto()
                            {
                                Id = a.Id,
                                Address = a.Address,
                                AppID = a.AppID,
                                LinuxId = a.LinuxId,
                                Name = a.Name,
                                OutPort = a.OutPort,
                                ProjectId = a.ProjectId,
                                StateCode = a.StateCode,
                                Version = a.Version,
                                Model = d != null ? new ModelInfoDto()
                                {
                                    Code = d.Code
                                } : null
                            };
                var pagedResultDto = new PagedResultDto<AppInfoListDto>();
                pagedResultDto.TotalCount = await query.CountAsync();
                var userList = await query.OrderBy(x=>x.Id).Page(page, size).ToListAsync();
                pagedResultDto.Items = await query.ToListAsync();
                return pagedResultDto;
            }
            else
            {
                var query = _dbContext.AppInfo.Where(t => 1 == 1).OrderByDescending(xy => xy.Id);
                var pagedResultDto = new PagedResultDto<AppInfoListDto>();
                pagedResultDto.TotalCount = await query.CountAsync();
                var userList = await query.OrderBy(x=>x.Id).Page(page, size).ToListAsync();
                var temList = ObjectMapper.Map<List<AppInfo>, List<AppInfoListDto>>(userList);
                pagedResultDto.Items = temList;
                return pagedResultDto;
            }
        }

        /// <summary>
        /// 根据服务或者项目ID读取运行的容器
        /// </summary>
        /// <param name="serviceid"></param>
        /// <param name="projectid"></param>
        /// <returns></returns>
        [HttpGet]
        public async Task<dynamic> SearchApp(int serviceid=0,int projectid=0)
        {
                var _query = from a in _dbContext.AppInfo
                            join b in _dbContext.ModelInfo on a.ModelId equals b.Id into c from m in c.DefaultIfEmpty()
                            join e in _dbContext.ProjectInfo on a.ProjectId equals e.Id into g from p in g.DefaultIfEmpty()
                            join h in _dbContext.ServiceInfo on a.ServiceId equals h.Id into k from s in k.DefaultIfEmpty()
                            select new 
                            {
                                id=a.Id,
                                name=a.Name,
                                appid=a.AppID,
                                modelid =a.ModelId,
                                serviceid=a.ServiceId,
                                projectid=a.ProjectId,
                                state=a.StateCode,
                                version=a.Version,
                                model = m != null ? new {
                                 id=m.Id,
                                 code=m.Code
                                }:null,
                                service = s != null ? new {
                                  id=s.Id,
                                  name=s.Name,
                                  code=s.Code
                                }:null,
                                project = p != null ? new {
                                  id=p.Id,
                                  name=p.Name,
                                  code=p.Code
                                }:null
                            };

            var list = await _query.Where(x=>x.state == RunState.running && x.id!=0).WhereIf(serviceid != 0, x => x.serviceid == serviceid).WhereIf(projectid != 0, x => x.projectid == projectid).ToListAsync();
            return list;
        }


        /// <summary>
        /// 根据ID获取单项Container
        ///</summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpGet]
        public AppInfoDto GetByIdAsync(int id)
        {
            var query = _dbContext.AppInfo.Where(t => t.Id == id).FirstOrDefault();
            var temList = ObjectMapper.Map<AppInfo, AppInfoDto>(query);
            return temList;
        }

        /// <summary>
        /// 删除某一个
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpPost]
        [TypeFilter(typeof(RoleAttribute), Arguments = new object[] { "data", "del" })]
        public async Task<string> Remove(int id)
        {
            var query =await _dbContext.AppInfo.Where(t => t.Id == id).FirstOrDefaultAsync();
            if(query!=null && query != default)
            {
                var nowday = DateTime.Now.AddHours(-1);
                if(query.CreateDate<nowday && query.StateCode != RunState.running)
                {
                    _dbContext.Remove(query);
                    await _dbContext.SaveChangesAsync();
                }
                else
                {
                    throw new PasteCodeException("刚创建或者状态不符的不能删除，为了防止误删除创建一个小时后才能删除！");
                }
            }
            else
            {
                throw new PasteCodeException("没有找到这个数据，无法继续执行操作！");
            }
            return "删除成功！";
        }
        
        ///// <summary>
        ///// 读取AddDto的数据模型 用于新增
        ///// </summary>
        ///// <returns></returns>
        //[HttpGet]
        //[TypeFilter(typeof(RoleAttribute), Arguments = new object[] { "data", "view" })]
        //public VoloModelInfo ReadAddModel()
        //{
        //    var _model = PasteBuilderHelper.ReadModelProperty<AppInfoAddDto>(new AppInfoAddDto());
        //    return _model;
        //}

        ///// <summary>
        ///// 读取Dto的数据模型 用于更新
        ///// </summary>
        ///// <returns></returns>
        //[HttpGet]
        //[TypeFilter(typeof(RoleAttribute), Arguments = new object[] { "data", "view" })]
        //public async Task<VoloModelInfo> ReadUpdateModel(int id)
        //{
        //    var _info = await _dbContext.AppInfo.Where(x => x.Id == id).AsNoTracking().FirstOrDefaultAsync();
        //    if (_info == null || _info == default)
        //    {
        //        throw new PasteCodeException("查询的信息不存在，无法执行编辑操作！");
        //    }
        //    var dto = ObjectMapper.Map<AppInfo, AppInfoUpdateDto>(_info);
        //    var _dataModel = PasteBuilderHelper.ReadModelProperty<AppInfoUpdateDto>(dto);
        //    return _dataModel;
        //}

        /// <summary>
        /// 读取Dto的数据模型 用于查看详情
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        [TypeFilter(typeof(RoleAttribute), Arguments = new object[] { "data", "view" })]
        public async Task<VoloModelInfo> ReadDetailModel(int id)
        {
            var _info = await _dbContext.AppInfo.Where(x => x.Id == id).AsNoTracking().FirstOrDefaultAsync();
            if (_info == null || _info == default)
            {
                throw new PasteCodeException("查询的信息不存在，无法执行编辑操作！");
            }
            var dto = ObjectMapper.Map<AppInfo, AppInfoDto>(_info);
            var _dataModel = PasteBuilderHelper.ReadModelProperty<AppInfoDto>(dto);
            return _dataModel;
        }

        /// <summary>
        /// 读取ListDto的数据模型
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        [TypeFilter(typeof(RoleAttribute), Arguments = new object[] { "data", "view" })]
        public VoloModelInfo ReadListModel()
        {
            var _model = PasteBuilderHelper.ReadModelProperty<AppInfoListDto>(new AppInfoListDto());
            var _query_model = PasteBuilderHelper.ReadModelProperty(new InputSearchBase());
            if (_query_model != null)
            {
                _model.QueryProperties = _query_model.Properties;
            }
            return _model;
        }

        /// <summary>
        /// 按页获取数据
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpGet]
        [TypeFilter(typeof(RoleAttribute), Arguments = new object[] { "data", "view" })]
        public async Task<PagedResultDto<AppInfoListDto>> Page([FromQuery]InputSearchBase input)
        {
            var query = _dbContext.AppInfo.Where(t => 1 == 1).OrderByDescending(x=>x.Id);
            var _pagedto = new PagedResultDto<AppInfoListDto>();
            _pagedto.TotalCount = await query.CountAsync();
            var userList = await query.Page(input.page, input.size).ToListAsync();
            var temList = ObjectMapper.Map<List<AppInfo>, List<AppInfoListDto>>(userList);
            _pagedto.Items = temList;
            return _pagedto;
        }
    }
}
